﻿//#include <QCoreApplication>
#include<btBulletDynamicsCommon.h>



int main(int argc, char *argv[])
{
//    QCoreApplication a(argc, argv);

//    return a.exec();

    //创建默认的碰撞设置
    btDefaultCollisionConfiguration * collisionConfiguration=new btDefaultCollisionConfiguration();

    //创建默认的碰撞dispatcher,需要把设置放进去

    btCollisionDispatcher * dispatcher=new btCollisionDispatcher(collisionConfiguration);


    /**
     * @brief dispatcher
     * btAxisSweep3 适用于处理大量的静态和动态物体，而 btDbvtBroadphase 则适用于大部分物体静止的情况。选择使用哪个宽相位算法通常取决于具体的应用场景和性能要求。
     */
    //碰撞检测的方式
    btBroadphaseInterface * overLappingPairCache=new btDbvtBroadphase;


    //这里创建一个约束器，应该是约束各个组成的关节
    btSequentialImpulseConstraintSolver *solver=new btSequentialImpulseConstraintSolver;


    //下面这里创建一个离散的动力学世界
    btDiscreteDynamicsWorld *dynamicsWorld=new btDiscreteDynamicsWorld(dispatcher,overLappingPairCache,solver,collisionConfiguration);


    //下面开始对这个离散世界进行设置
    //x 分量表示向右或向左的力。
    //y 分量表示向上或向下的力。
    //z 分量表示前后或前后的力。
    dynamicsWorld->setGravity(btVector3(0,-10,0));

    //上面就是初始化的内容


    btAlignedObjectArray<btCollisionShape *>  collisionShapes;

    {
        btCollisionShape * groundShape=new btBoxShape(btVector3(btScalar(50.f),btScalar(50.f),btScalar(50.f)));
        collisionShapes.push_back(groundShape);

        btTransform groundTransform;
        groundTransform.setIdentity();
        groundTransform.setOrigin(btVector3(0,-56,0));
        btScalar mass(0.);

        //用mass来判断是不是静态的物体
        bool isDynamic=(mass != 0.f);

        btVector3 localInertia(0.,0.,0.);
        if(isDynamic){
            //这个库怪的很，老是把参数传进去然后修改参数
            groundShape->calculateLocalInertia(mass,localInertia);
        }

        btDefaultMotionState *myMotionState=new btDefaultMotionState(groundTransform);
        btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia);
        btRigidBody *body=new btRigidBody(rbInfo);

        dynamicsWorld->addRigidBody(body);


    }

    {
        //这里创建另外一个刚体
        btCollisionShape * colShape=new btSphereShape(btScalar(1.0));
        collisionShapes.push_back(colShape);

        //这里创建的是一个动态的刚体
        btTransform startTransForm;
        startTransForm.setIdentity();

        //东西有质量，是动态的
        btScalar mass(1.f);
        bool isDynamic = (mass!=0.f);

        btVector3 localInnertia(0,0,0);
        if(isDynamic){
            colShape->calculateLocalInertia(mass,localInnertia);
        }

        startTransForm.setOrigin(btVector3(2,10,0));

        btDefaultMotionState *myMotionState=new btDefaultMotionState(startTransForm);
        btRigidBody::btRigidBodyConstructionInfo rbinf(mass,myMotionState,colShape,localInnertia);
        btRigidBody *body=new btRigidBody(rbinf);

        dynamicsWorld->addRigidBody(body);






    }








    for(int i=0;i<500;i++){
        //60帧，步长为10
        dynamicsWorld->stepSimulation(1.f/60.f,10);

        //这里打印出所有的碰撞的position
        for(int j=dynamicsWorld->getNumCollisionObjects()-1;j>=0;j--){
            btCollisionObject *obj=dynamicsWorld->getCollisionObjectArray()[j];
            btRigidBody * body=btRigidBody::upcast(obj);
            btTransform trans;
            if(body && body->getMotionState()){
//                body->getMotionState()->setWorldTransform(trans);
                body->getMotionState()->getWorldTransform(trans);

            }else{
                trans=obj->getWorldTransform();
            }
            printf("world pos object %d = %f %f %f\n",j,float(trans.getOrigin().getX()),float(trans.getOrigin().getY()),float(trans.getOrigin().getZ()));


        }


    }


    //从离散世界中移除刚体
    for(int i=dynamicsWorld->getNumCollisionObjects()-1;i>=0;i--){
        btCollisionObject * obj=dynamicsWorld->getCollisionObjectArray()[i];
        btRigidBody *body=btRigidBody::upcast(obj);
        if(body && body->getMotionState()){
            delete body->getMotionState();
        }
        dynamicsWorld->removeCollisionObject(obj);
        delete obj;

    }

    //删除碰撞的形状？
    for(int j=0;j<collisionShapes.size();j++){
        btCollisionShape *shape=collisionShapes[j];
        collisionShapes[j] = 0;
        delete  shape;
    }

    //这里就一个一个删除
    delete dynamicsWorld;


    delete solver;

    delete overLappingPairCache;

    delete dispatcher;

    delete  collisionConfiguration;

    collisionShapes.clear();


}
